local Msg = require("core.Msg")
local Lang = require("common.Lang")
local ObjHuman = require("core.ObjHuman")
local Broadcast = require("broadcast.Broadcast")
local EquipLogic = require("bag.EquipLogic")
local BagLogic = require("bag.BagLogic")
local EquipExcel = require("excel.Equip")
local StageConfig = require("excel.EquipStage")
local Grid = require("bag.Grid")
local RefineDefine = require("refine.RefineDefine")
local XlLogic = require("refine.XlLogic")
local RefineHandle = require("refine.HandlerL")
local HtmlUtil = require("common.HtmlUtil")
local ItemDefine = require("bag.ItemDefine")
local Log = require("common.Log")
local Status = require("scene.Status")
local TaskCallbacks = require("task.TaskCallbacks")
local TaskDefine = require("task.Define")
local YYDaBiao = require("activity.operate.DaBiao")
local AcvityDefine = require("activity.Define")
local OfficialLogic = require("official.OfficialLogic")

function isItemEnough(human, grid)
  local pos = EquipExcel.equip[grid.id].pos
  local equipStageConfig = StageConfig[pos]
  local thisConfig = nil
  for i=1, #equipStageConfig do
    if equipStageConfig[i].curEquipId == grid.id then
      thisConfig = equipStageConfig[i]
      break
    end
  end
  if not thisConfig then
    return false
  end
  local isEnough = true
  for i=1, #thisConfig.needItem do
    if BagLogic.getItemCount(human, thisConfig.needItem[i][1]) < thisConfig.needItem[i][2] then
      isEnough = false
    end  
  end  
  if ObjHuman.getYinliang(human) < thisConfig.needYinliang or not isEnough then
      return false
  end
  return true
end

function canStage(human, grid)
  local needLv = 0
  local thisConfig = StageConfig[EquipExcel.equip[grid.id].pos]  
  for j=1, #thisConfig do    
    if thisConfig[j].curEquipId == grid.id then
      needLv = thisConfig[j].needLv
      if human.db.lv >= thisConfig[j].needLv then
        return true, thisConfig[j].needLv
      end
    end
  end
  return false,needLv
end

function isSpecPos(pos)
  if pos ~= 1 and pos ~= 10 and pos ~= 11 and pos ~= 12 and pos ~= 13 then
    return false
  end
  return true
end

function sendEquipStatus(human, sendMsg)
  for i=0, human.db.equipLen - 1 do
    if human.db.equip[i].id ~= 0 then
      if isSpecPos(EquipExcel.equip[human.db.equip[i].id].pos) and canStage(human, human.db.equip[i])
        and isItemEnough(human, human.db.equip[i]) then
        sendMsg.status[i+1] = 0
      end
    end 
  end
  for i=1, sendMsg.status[0] do
    if not sendMsg.status[i] then
      sendMsg.status[i] = 1
    end
  end
  sendMsg.qhInfo[0] = 0
  sendMsg.type = 2
  Msg.send(sendMsg, human.fd)
end

function checkCanStage(human, grid)
  if isSpecPos(EquipExcel.equip[grid.id].pos) and canStage(human, grid) then
    return true, nil
  end
  local maxLv, type = open(human, true)
  if type == 2 then
    if maxLv > EquipExcel.equip[grid.id].lv then
      return true, maxLv, type
    end
  elseif type == 3 and canStage(human, grid) then
    return true, maxLv, type
  end
  return false, maxLv, type
end


function open(human, noSend)
  local sendMsg = Msg.gc.GC_EQUIP_OPEN
  sendMsg.status[0] = human.db.equipLen
  local canStagLen = 0
  local maxLv = 0
--  local sjEquipLv = {}
  local commEquip = {}
  for i=0, human.db.equipLen -1 do
    local grid = human.db.equip[i]
    if grid.id ~= 0 and not isSpecPos(EquipExcel.equip[grid.id].pos) then
      commEquip[#commEquip + 1] = grid
      maxLv = math.max(maxLv, EquipExcel.equip[grid.id].lv)
    end
  end
   for i=0, human.db.equipLen -1 do
    local grid = human.db.equip[i]
    if grid.id ~= 0 and not isSpecPos(EquipExcel.equip[grid.id].pos) then
      if EquipExcel.equip[grid.id].lv == maxLv then
        canStagLen = canStagLen + 1
      end
    end
  end
  --装备没穿齐
  if #commEquip ~= 8 then
    for i=0, human.db.equipLen -1 do
      sendMsg.status[i+1] = 1
    end
    if not noSend then
      return sendEquipStatus(human, sendMsg)
    end
    return maxLv, 1
  end
  --某些装备没有达到统一等阶
  if canStagLen ~= 8 then
    for i=0, human.db.equipLen -1 do
      local grid = human.db.equip[i]
      if grid.id ~= 0 then
        if EquipExcel.equip[grid.id].lv < maxLv and isItemEnough(human, human.db.equip[i]) then
          sendMsg.status[i+1] = 0
        else
          sendMsg.status[i+1] = 1
        end
      end 
    end
    if not noSend then
      return sendEquipStatus(human, sendMsg)
    end
    return maxLv, 2
  end
  --可升阶
  for i=0, human.db.equipLen -1 do
    local grid = human.db.equip[i]
    if grid.id ~= 0 then
      if canStage(human, grid) and isItemEnough(human, human.db.equip[i]) then
        sendMsg.status[i+1] = 0
      else
        sendMsg.status[i+1] = 1
      end
    end
  end
  if not noSend then
    return sendEquipStatus(human, sendMsg)
  end
  return maxLv, 3
end

function chooseEquip(human, index, noSend)
  local sendMsg = Msg.gc.GC_CHOOSE_EQUIP  
  local grid = human.db.equip[index]
  local equip = grid.data.equip
  local thisConfig = StageConfig[EquipExcel.equip[grid.id].pos]  
  sendMsg.showRand = 0
  sendMsg.type = 2
  sendMsg.jipin[0] = 0
  local cache = {}
  local CanStage = false
  for i=1, #thisConfig do    
    if thisConfig[i].curEquipId == grid.id then
        sendMsg.needItem[0] = #thisConfig[i].needItem        
        for j=1, #thisConfig[i].needItem do
          Grid.create(cache, thisConfig[i].needItem[j][1], thisConfig[i].needItem[j][2])
          Grid.makeItem(cache, sendMsg.needItem[j], 0, human)
        end
        sendMsg.stageNextLv = EquipExcel.equip[grid.id].strengthenLv
        sendMsg.needYinliang = thisConfig[i].needYinliang
        sendMsg.nextAddAttr[0] = #EquipExcel.equip[grid.id].baseAttr
        for j=1, #EquipExcel.equip[grid.id].baseAttr do
          sendMsg.nextAddAttr[j].key = EquipExcel.equip[thisConfig[i].nextEquipId].baseAttr[j][1]
          sendMsg.nextAddAttr[j].value = EquipExcel.equip[thisConfig[i].nextEquipId].baseAttr[j][2] * (1 + EquipExcel.equipQulity[equip.quality].attrAddRate)
              - EquipExcel.equip[thisConfig[i].curEquipId].baseAttr[j][2] * (1+ EquipExcel.equipQulity[equip.quality].attrAddRate)
        end
        sendMsg.nextEquip[0] = 1
        Grid.create(cache, thisConfig[i].nextEquipId, 1, false, equip.quality, nil, equip.strengthLv)
        Grid.makeItem(cache, sendMsg.nextEquip[1], 0, human)
        local isCan, maxLv, type = checkCanStage(human, grid)
        if isCan and type == 2 then
          sendMsg.isMax = 3
          CanStage = true
        end
        if isCan then
          sendMsg.isMax = 0
          CanStage = true        
        end        
    end
  end
  if not CanStage then
    sendMsg.isMax = 2
  end
  if noSend then
    return CanStage
  else
    Msg.send(sendMsg, human.fd)
  end
end

function shengjie(human, index)
  local grid = human.db.equip[index]
  local id = grid.id
  local pos = EquipExcel.equip[grid.id].pos
  local equipStageConfig = StageConfig[pos]
  local tmpId = grid.id
  local thisConfig = nil
  local isBro = 1
  for i=1, #equipStageConfig do
    if equipStageConfig[i].curEquipId == grid.id then
      thisConfig = equipStageConfig[i]
      isBro = i
      break
    end
  end
  if not thisConfig then
    return 
  end
  if human.db.lv < thisConfig.needLv then
    return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.REFINE_SHENGJIE_LV_NOT_ENOUGH)
  end
  local maxLv, type = open(human, true)
  if type == 1 and not isSpecPos(pos) then
    return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.REFINE_SHENGJIE_EQUIP_NOT_ENOUGH)
  end
  if type == 2 and not isSpecPos(pos) and EquipExcel.equip[grid.id].lv >= maxLv then
    return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.REFINE_SHENGJIE_EQUIP_LV_NOT_ENOUGH)
  end
  for i=1, #thisConfig.needItem do
    if BagLogic.getItemCount(human, thisConfig.needItem[i][1]) <thisConfig.needItem[i][2] then
      chooseEquip(human, index)
      return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.REFINE_SHENGJIE_ITEM_NOT_ENOUGH)    
    end     
  end
  if ObjHuman.getYinliang(human) < thisConfig.needYinliang then
    chooseEquip(human, index)
    return Broadcast.sendBroadcast(human, Lang.DOWN, Lang.REFINE_YINLIANG_NOT_ENOUGH)
  end
  for i=1, #thisConfig.needItem do
    BagLogic.delItemsById(human, thisConfig.needItem[i][1], thisConfig.needItem[i][2], "shengjie")
  end
  ObjHuman.decYinliang(human, thisConfig.needYinliang, "qianghua")
  human.db.equip[index].id = thisConfig.nextEquipId
  XlLogic.upXilianAttr(human, index)
  EquipLogic.GC_EQUIP_CHANGE(human,index)  
  chooseEquip(human, index)
  open(human)
  RefineDefine.sendStatus(human, RefineDefine.REFINE_SHENGJIE_SUCCESS)
  ObjHuman.doCalc(human)
  RefineHandle.CG_OPEN_REFINE_WINDOW(human)
  if pos == 4 then
    Status.sendViewStatus(human, true)
  end
  if isBro > 1 then
    local grid1 = Grid.create(nil, tmpId, 1, 1)
    local bro = string.format(Lang.REFINE_SHENGJIE_BROCAST, HtmlUtil.fontName(human.name, human._id), ItemDefine.getValue(tmpId, "lv"),
      HtmlUtil.fontItem(grid1), ItemDefine.getValue(grid.id, "lv"), HtmlUtil.fontItem(grid))
    Broadcast.sendBroadcast2World(Lang.UP + Lang.GROSSIP, bro)
  end
  YYDaBiao.checkCanGet(human, AcvityDefine.OPERATEACT_TYPE_EQUIPSTAGE)
  TaskCallbacks.taskRefineCB(human, TaskDefine.TASK_REFINE_UPGRADE, EquipExcel.equip[id].pos)
  OfficialLogic.checkOneCondition(human, "strengthLv")
  
  Log.write(Log.LOGID_OSS_REFINE_SJ, human._id,human.account,human.name,human.db.lv,id,EquipExcel.equip[id].pos,EquipExcel.equip[id].lv,EquipExcel.equip[thisConfig.nextEquipId].lv,thisConfig.nextEquipId)
end

function checkShowTips(human, info)
  if human.db.lv < 20 then
    return 0
  end
  local cache = {}
  for i=0,human.db.equipLen - 1 do
    local grid = human.db.equip[i]
    if grid ~= nil and grid.id ~= 0 then
      local grid = human.db.equip[i]
      local pos = EquipExcel.equip[grid.id].pos
      local equipStageConfig = StageConfig[pos]
      local thisConfig = nil
      for i=1, #equipStageConfig do
        if equipStageConfig[i].curEquipId == grid.id then
          thisConfig = equipStageConfig[i]
          break
        end
      end
      if chooseEquip(human, i, true) then
        
        local isTrue = true
        for i=1, #thisConfig.needItem do
          if BagLogic.getItemCount(human, thisConfig.needItem[i][1]) < thisConfig.needItem[i][2]
            or ObjHuman.getYinliang(human) < thisConfig.needYinliang then
            isTrue = false
            break
          end
        end 
        if isTrue then
          if info then
            info.equip[0] = 1
            Grid.create(cache, thisConfig.curEquipId, 1)
            Grid.makeItem(cache, info.equip[1], 0, human)
          end
          return 1
        end
      end
    end
  end
  return 0
end

